package domein;

import java.util.List;

import persistentie.PersistentieController;

import domein.exceptie.InvalidCategorieException;
import domein.exceptie.SpelbordAlreadyExistsException;

public class LevelEditorController {
	
	private SpelbordRepository spelbordRepository;
	private SpelBord hetSpelbord;
	private Obstakel hetObstakel;
	private Personage hetPersonage;
	private boolean eindpositie=false;
	private boolean startpositie=false;
	private PersonageRepository personageRepository;
	
	public LevelEditorController(PersonageRepository personageRepository){
		this.spelbordRepository = new SpelbordRepository();
		this.personageRepository = personageRepository;
	}
	
	/**
	 * Geeft al de spelborden terug met naam, breedte en hoogte
	 * @author Sam Verschueren
	 * @return de gegevens van de spelborden
	 */
	public String[][] geefSpelborden() {
		List<SpelBord> spelborden = this.spelbordRepository.geefSpelborden();
		
		String[][] res = new String[spelborden.size()][3];
		int teller=0;
		
		for(SpelBord spelbord:spelborden) {
			res[teller][0] = spelbord.getNaam();
			res[teller][1] = String.valueOf(spelbord.geefSpelBord()[0].length);
			res[teller][2] = String.valueOf(spelbord.geefSpelBord().length);
			
			teller++;
		}
		
		
		return res;
	}
	
	public String[][] geefObstakels() {
		List<Obstakel> obstakels = this.spelbordRepository.geefObstakels();
		
		String[][] res = new String[obstakels.size()][3];
		
		int teller=0;
		
		for(Obstakel obstakel:obstakels) {
			res[teller][0] = obstakel.getNaam();
			res[teller][1] = obstakel.geefTextWeergave();
			res[teller][2] = obstakel.getBestand();
			
			teller++;
			
		}
		
		return res;
	}
	
	/**
	 * Selecteert een spelbord aan de hand van de unieke naam
	 * @author Sam Verschueren
	 * @param naam De naam van het spelbord
	 * @return Het spelbord
	 */
	public String[][] selecteerSpelbord(String naam) {
		this.hetSpelbord = this.spelbordRepository.geefSpelbord(naam);
		
		return this.zetVakom(this.hetSpelbord.geefSpelBord());
	}
	
	/**
	 * Maakt een nieuw leeg spelbord aan in de databank.
	 * @author Sam Verschueren
	 * @param naam De naam van het spelbord.
	 * @param breedte De breedte van het spelbord.
	 * @param hoogte De hoogte van het spelbord.
	 * @return Het spelbord
	 * @throws SpelbordAlreadyExistsException 
	 */
	public String[][] maakSpelbord(String naam, int breedte, int hoogte) throws SpelbordAlreadyExistsException {
		this.hetSpelbord = this.spelbordRepository.maakSpelbord(naam, breedte, hoogte);
		
		return this.zetVakom(this.hetSpelbord.geefSpelBord());
	}

	public String[] selecteerVijand(String naam) {
		this.hetObstakel = null;
		this.eindpositie = false;
		this.startpositie = false;
		
		try {
			this.hetPersonage = new Personage(naam, this.personageRepository.geefPersonageCategorie(naam));
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvalidCategorieException e) {
			e.printStackTrace();
		}
		
		return null;
	}

	/**
	 * @author Sam Verschueren
	 * @param naam De naam van het obstakel
	 * @return Een array met de gegevens van het geselecteerde obstakel
	 */
	public String[] selecteerObstakel(String naam) {
		this.hetObstakel = this.spelbordRepository.geefObstakel(naam);
		this.hetPersonage = null;
		this.eindpositie = false;
		this.startpositie = false;
		
		String[] res = new String[2];
		res[0] = this.hetObstakel.getNaam();
		res[1] = this.hetObstakel.geefTextWeergave();
		
		return res;
	}

	public void selecteerEindpositie() {
		this.eindpositie = true;
		this.startpositie = false;
		this.hetObstakel = null;
		this.hetPersonage = null;
	}
	
	public void selecteerStartpositie() {
		this.eindpositie = false;
		this.startpositie = true;
		this.hetObstakel = null;
		this.hetPersonage = null;
	}

	public String[][] plaats(int posX, int posY) {
		if(this.hetSpelbord != null) {
			if(this.hetSpelbord.geefVak(posX, posY).isVrij()) {
				if(this.hetPersonage != null) {
					Vak vak = this.hetSpelbord.geefVak(posX, posY);
					vak.setPersonage(this.hetPersonage);
					
					this.hetPersonage.setVak(vak);
					
					PersistentieController.getInstance().plaatsVijand(this.hetSpelbord, this.hetPersonage, posX, posY);
				}
				else if(this.hetObstakel != null) {
					Vak vak = this.hetSpelbord.geefVak(posX, posY);
					vak.setObstakel(this.hetObstakel);
					
					PersistentieController.getInstance().plaatsObstakel(this.hetSpelbord, this.hetObstakel, posX, posY);
				}
				else if(this.eindpositie) {
					int[] einde = {posX, posY};
					
					this.hetSpelbord.setEindPositie(einde);
					
					PersistentieController.getInstance().zetEindPositie(this.hetSpelbord, einde);
				}
				else if(this.startpositie) {
					int[] start = {posX, posY};
					
					this.hetSpelbord.setStartPositie(start);
					
					PersistentieController.getInstance().zetStartPositie(this.hetSpelbord, start);
				}
			}
		}
		
		return this.zetVakom(this.hetSpelbord.geefSpelBord());
	}

	public void verwijder(int posX, int posY) {
		if(this.hetSpelbord != null) {
			if(!this.hetSpelbord.geefVak(posX, posY).isVrij()) {
				PersistentieController.getInstance().verwijderVijand(this.hetSpelbord, posX, posY);
				PersistentieController.getInstance().verwijderObstakel(this.hetSpelbord, posX, posY);
				
				Vak vak = this.hetSpelbord.geefVak(posX, posY);
				vak.setPersonage(null);
				vak.setObstakel(null);
			}
		}
	}

	public void verwijderSpelbord(String naam) {
		this.spelbordRepository.verwijderSpelbord(naam);
	}
	
	public String[][] geefSpelBord(){
		String[][] spelBord = this.zetVakom(hetSpelbord.geefSpelBord());		
		int[] eindPositie = hetSpelbord.getEindPositie();
		int[] startPositie = hetSpelbord.getStartPositie();
		
		spelBord[eindPositie[1]][eindPositie[0]] = "x";
		spelBord[startPositie[1]][startPositie[0]] = "@";
		
		return spelBord;
	}
	
	/**
	 * @author Stefan De Coen
	 * @param vak
	 * @return spelBord
	 */
	private String[][] zetVakom(Vak[][] vak) {
		String[][] spelBord = new String[vak.length][vak[0].length];

		for (int i = 0; i < vak.length; i++) {
			for (int j = 0; j < vak[i].length; j++) {
				spelBord[i][j] = vak[i][j].toString();
			}
		}

		return spelBord;
	}
}
